Testing
@nano_kit/router is designed to be easily testable by decoupling navigation logic from the browser’s History API.
Virtual Navigation
Section titled “Virtual Navigation”For testing environments (Unit tests, Integration tests) or isolated environments (Storybook), you should use virtualNavigation instead of browserNavigation.
virtualNavigation creates an in-memory history stack that works exactly like the browser router but without manipulating the window URL.
If your application uses Dependency Injection (DI) for router tokens (recommended), you can easily swap the real browser navigation with virtual navigation in your tests.
First, ensure your app defines tokens using browserNavigation$:
import { browserNavigation$ } from '@nano_kit/router'import { routes } from './routes'
/* Create factory for tokens */export const [Location$, Navigation$] = browserNavigation$(routes)Then in your tests, creating a context with overridden providers:
import { render, screen } from '@testing-library/react'import { InjectionContext, provide } from '@nano_kit/store'import { InjectionContextProvider } from '@nano_kit/react'import { virtualNavigation } from '@nano_kit/router'import { Location$, Navigation$ } from './router'import { App } from './App'
it('should render allowed page', async () => { /* Create virtual navigation for the test */ const [$location, navigation] = virtualNavigation('/admin')
/* Override tokens with virtual instances */ const context = new InjectionContext([ provide(Location$, $location), provide(Navigation$, navigation) ])
render( <InjectionContextProvider context={context}> <App /> </InjectionContextProvider> )
expect(screen.getByText('Admin Panel')).toBeInTheDocument()})